package com.ezops.ui;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.activiti.engine.IdentityService;
import org.activiti.engine.TaskService;
import org.activiti.engine.identity.User;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.ezops.businessprocess.integration.identity.EzopsUser;
import com.ezops.dto.TradeExceptionTaskDTO;
import com.ezops.dto.TradeTasksClaimDTO;
import com.ezops.model.EzopsOTModel;
import com.ezops.model.EzopsUserProfile;
import com.ezops.model.FieldValidationError;
import com.ezops.poc.bo.AssetLookUp;
import com.ezops.poc.bo.ClientLookUp;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@RestController
public class TradeExceptionResource {

	@Autowired
	protected TaskService taskService;

	@Autowired
	private IdentityService identityService;
	
	@Autowired
	private ClientLookUp clientLookUp;
	
	@Autowired
	private AssetLookUp assetLookUp;
	

	public static ObjectMapper mapper = new ObjectMapper();
	
	private SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss");

	@RequestMapping(value = "/ezops/tradetasks", method = RequestMethod.GET, produces = "application/json")
	public List<TradeExceptionTaskDTO> getTasks() throws JsonParseException,
			JsonMappingException, IOException {

		TaskQuery query = taskService.createTaskQuery();
		List<Task> tasks = query.taskUnassigned()
				.taskDefinitionKey("usertask1").includeProcessVariables()
				.list();

		List<TradeExceptionTaskDTO> dtos = new ArrayList<TradeExceptionTaskDTO>();
		for (Task task : tasks) {
			TradeExceptionTaskDTO dto = new TradeExceptionTaskDTO();
			dto.setCreationTime(dateFormat.format(task.getCreateTime()));
			dto.setTaskId(task.getId());
			EzopsOTModel model = mapper.readValue(task.getProcessVariables()
					.get("message").toString(), EzopsOTModel.class);
			dto.setAsset(assetLookUp.reverseLookUp(model.getAssetId()));
			dto.setClient(clientLookUp.reverseLookUp(model.getClientId()));
			dto.setClientTradeID(model.getClientTradeId());
			dto.setEzopsId(model.getEzOpsId());
			dto.setFileName(model.getFileName());

			dtos.add(dto);
		}

		return dtos;
	}

	@RequestMapping(value = "/ezops/mytasks/{userId}", method = RequestMethod.GET, produces = "application/json")
	public List<TradeExceptionTaskDTO> getMyTasks(
			@PathVariable("userId") String userId) throws JsonParseException,
			JsonMappingException, IOException {

		TaskQuery query = taskService.createTaskQuery();
		List<Task> tasks = query.taskAssignee(userId)
				.taskDefinitionKey("usertask1").includeProcessVariables()
				.list();

		List<TradeExceptionTaskDTO> dtos = new ArrayList<TradeExceptionTaskDTO>();
		for (Task task : tasks) {
			TradeExceptionTaskDTO dto = new TradeExceptionTaskDTO();
			dto.setCreationTime(dateFormat.format(task.getCreateTime()));
			dto.setTaskId(task.getId());
			EzopsOTModel model = mapper.readValue(task.getProcessVariables()
					.get("message").toString(), EzopsOTModel.class);
			dto.setAsset(assetLookUp.reverseLookUp(model.getAssetId()));
			dto.setClient(clientLookUp.reverseLookUp(model.getClientId()));
			dto.setClientTradeID(model.getClientTradeId());
			dto.setEzopsId(model.getEzOpsId());
			dto.setFileName(model.getFileName());

			dtos.add(dto);
		}

		return dtos;
	}

	@RequestMapping(value = "/ezops/claimtask", method = RequestMethod.POST, produces = "application/json")
	public void claimTask(@RequestParam("userId") String userId,
			@RequestParam("taskId") String taskId) {

		taskService.setAssignee(taskId, userId);
	}

	@RequestMapping(value = "/ezops/assigntask", method = RequestMethod.POST, produces = "application/json")
	public void assigntasks(@RequestBody TradeTasksClaimDTO tradetask) {
		String userId = tradetask.getUserId();

		for (String taskId : tradetask.getTaskIds()) {

			taskService.setAssignee(taskId, userId);
		}

	}

	@RequestMapping(value = "/ezops/users", method = RequestMethod.GET, produces = "application/json")
	public List<EzopsUserProfile> getUsers() {

		List<User> users = identityService.createUserQuery().list();

		List<EzopsUserProfile> dtos = new ArrayList<EzopsUserProfile>();
		for (User user : users) {
			if (user instanceof EzopsUser) {
				dtos.add(((EzopsUser) user).getUserProfile());
			}
		}

		return dtos;
	}

	@RequestMapping(value = "/ezops/taskdata/{taskId}", method = RequestMethod.GET, produces = "application/json")
	public List<FieldValidationError> getTaskData(@PathVariable String taskId)
			throws JsonParseException, JsonMappingException, IOException {

		Task task = taskService.createTaskQuery().taskId(taskId)
				.includeProcessVariables().singleResult();

		String fieldErrorJson = task.getProcessVariables().get("exceptions")
				.toString();
		mapper.getSerializationConfig().withSerializationInclusion(JsonInclude.Include.NON_NULL);

		List<FieldValidationError> errors = mapper.readValue(fieldErrorJson,
				List.class);

		return errors;
	}

}
